package com.micromall.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.micromall.common.exception.BusiException;
import com.micromall.common.payment.ISPaymentRequest;
import com.micromall.common.utils.*;
import com.micromall.model.*;
import com.micromall.model.vo.BusiOrderVO;
import com.micromall.model.vo.CartVO;
import com.micromall.service.*;
import com.micromall.service.strategy.IDiscountStrategy;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.micromall.common.base.BaseController;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * <p>
 * 订单表  前端控制器
 * </p>
 * @author Dante Fung
 * @since 2017-07-26
 */
@Controller
@RequestMapping("/busiOrder")
public class BusiOrderController extends BaseController {

    public static final Logger logger = LoggerFactory.getLogger(BusiOrderController.class);


    @Autowired private IBusiOrderService busiOrderService;
    @Autowired private IBusiOrderItemService busiOrderItemService;
    @Autowired private IDiscountStrategy discountStrategy;
    
    @RequestMapping("/manager")
    public String manager() {
        return "order/order";
    }


    @RequestMapping("/dataGrid")
    public String dataGrid(HttpServletRequest request, BusiOrder busiOrder, Integer page, Integer rows, String sort, String order, RedirectAttributes redirectAttributes) {
        String queryType = request.getParameter("queryType");
        String phoneNo = request.getParameter("phoneNo");
        String smsCode = request.getParameter("smsCode");
        String validateCodeFromOrderPage = request.getParameter("validateCode");

        StringBuilder errorMessage = new StringBuilder();
        if (StringUtils.isBlank(phoneNo)) {
            errorMessage.append("手机号不能为空!");
        }

        if (StringUtils.isBlank(validateCodeFromOrderPage)) {
            if (StringUtils.isBlank(smsCode)) {
                errorMessage.append("短信验证码不能为空!");
            }
            if (StringUtils.isNotBlank(errorMessage.toString())) {
                throw  new BusiException(errorMessage.toString());
            }
            // 验证码校验
            String smsCodeCache = (String) request.getSession().getAttribute("smsCode");
            if (!smsCode.equalsIgnoreCase(smsCodeCache)) {
                // throw  new BusiException("短信验证码校验失败!");
                redirectAttributes.addFlashAttribute("errorMessage", "短信验证码校验失败!");
                return "redirect:/busiOrder/askphone";
            } else {
                String validateCode = MD5Util.getMD5String(ValidateUtil.genSmsValidateCode());
                request.getSession().setAttribute("validateCode", validateCode);
                request.setAttribute("validateCode",validateCode);
                return "redirect:/busiOrder/dataGrid?phoneNo="+phoneNo+"&validateCode="+validateCode;
            }
        }

        String validateCodeCache = (String) request.getSession().getAttribute("validateCode");
        if (!validateCodeFromOrderPage.equalsIgnoreCase(validateCodeCache)) {
            return "redirect:/busiOrder/askphone";
        }

        // 1、设置条件.
        if (Dict.BusiOrder.Query_Type.PAYED.getCode().equalsIgnoreCase(queryType)) {
            busiOrder.setPayStatus(Dict.BusiOrder.PayStatus.PAYED.getCode());
        }
        if (Dict.BusiOrder.Query_Type.TOPAY.getCode().equalsIgnoreCase(queryType)) {
            busiOrder.setPayStatus(Dict.BusiOrder.PayStatus.TOPAY.getCode());
        }
        if (Dict.BusiOrder.Query_Type.TOCOMMENT.getCode().equalsIgnoreCase(queryType)) {
            busiOrder.setPayStatus(Dict.BusiOrder.PayStatus.PAYED.getCode());
            // TODO: 设置是否已评价字段..
        }
        // 判断用户是否注册过.
        String retCode = miMemberService.hadExistAutoRegister(phoneNo, phoneNo);
        if (Dict.Sys_User.RegisterStatusCode.AUTO_REGISTER_FAIL.getCode().equalsIgnoreCase(retCode)) {
            throw new BusiException("系统异常:用户自动注册失败!业务操作无法进行!");
        } else if (Dict.Sys_User.RegisterStatusCode.AUTO_REGISTER_SUCCESS.getCode().equalsIgnoreCase(retCode)) {
            if (logger.isDebugEnabled()) {
                logger.info(Dict.Sys_User.RegisterStatusCode.AUTO_REGISTER_SUCCESS.getName());
            }
        } else if (Dict.Sys_User.RegisterStatusCode.HAD_EXIST.getCode().equalsIgnoreCase(retCode)) {
            if (logger.isDebugEnabled()) {
                logger.info(Dict.Sys_User.RegisterStatusCode.HAD_EXIST.getName());
            }
        }
        busiOrder.setMemberNo("WS"+phoneNo);
        busiOrder.setDataStatus(Dict.YesOrNo.Yes.getCode());

        EntityWrapper<BusiOrder> ew = new EntityWrapper<BusiOrder>();
        ew.setEntity(busiOrder);
        String mode = request.getParameter("mode");
        if (null == rows) {  rows = 30; }
        if (null == page) { page = 0; }
        if (StringUtils.isBlank(order)) { order="desc"; }
        if (StringUtils.isBlank(sort)) { sort = "id"; }
//        if (StringUtils.isBlank(queryType)) { queryType = Dict.BusiOrder.Query_Type.ALL.getCode(); }
        Page<BusiOrder> pages = getPage(page, rows, sort, order);
        pages = busiOrderService.selectPage(pages,ew);
        List<BusiOrder> orders = pages.getRecords();
        List orderVoList = new ArrayList();
        BusiOrderItem orderItemQuery = null;
        EntityWrapper<BusiOrderItem> entityWrapper = new EntityWrapper<BusiOrderItem>();
        for (BusiOrder orderQ : orders) {
            String id = orderQ.getId()+"";
            orderItemQuery = new BusiOrderItem();
            orderItemQuery.setOrderId(id);
            orderItemQuery.setStandy3(Dict.YesOrNo.Yes.getCode());
            entityWrapper.setEntity(orderItemQuery);
            List<BusiOrderItem> busiOrderItems = busiOrderItemService.selectList(entityWrapper);
            BusiOrderVO vo = new BusiOrderVO();
            BeanUtils.copy(orderQ, vo);
            vo.setBusiOrderItemList(busiOrderItems);
            orderVoList.add(vo);
        }
        pages.setRecords(orderVoList);
        request.setAttribute("validateCode", validateCodeCache);
        request.setAttribute("phoneNo", phoneNo);
        request.setAttribute("pageInfo", pages);
        request.setAttribute("queryType", queryType);
        request.setAttribute("devMode", "dev".equalsIgnoreCase(mode)?JSONObject.toJSONString(pages):"");
        return "order/order";
    }


    // TODO:需要重构至Service层中
    @Autowired
    private IBusiCartService busiCartService;
    @Autowired
    private IBusiCartDetailItemService busiCartDetailItemService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private IBusiProductService busiProductService;
    @Autowired
    private IBusiCategroyService categroyService;
    @Autowired
    private IBusiProdCategoryService prodCategoryService;
    @Autowired
    private IMiMemberService miMemberService;
    @Autowired
    private IAlRegionService alRegionService;

    /**
     * 1、购物车页面-订单确认页面-点击结算跳转到此方法.from=cart
     * 2、查看商品详情页面-订单确认页面-点击立即购买跳转到此方法 from=productDetail
     * 确认订单页面
     */
    @RequestMapping("/confirm")
    public String confirmPage(String from, HttpServletRequest request, RedirectAttributes redirectAttributes) {
        String phoneNo = request.getParameter("phoneNo");
        String receiverName = request.getParameter("receiverName");
        String areaId = request.getParameter("areaId");
        String address = request.getParameter("address");// 详细收货地址
        String smsCode = request.getParameter("smsCode");

        String REDIRECT_PAGE = "redirect:/busiOrder/confirmPage?from=%s&%s";
        if ("productDetail".equalsIgnoreCase(from)) {
            REDIRECT_PAGE = String.format(REDIRECT_PAGE, from, "productId="+request.getParameter("productId"));
        } else if ("cart".equalsIgnoreCase(from)) {
            REDIRECT_PAGE = String.format(REDIRECT_PAGE, from, "cartId="+request.getParameter("cartId"));
        }

        // 校验
        StringBuilder errorMessage = new StringBuilder();
        if (StringUtils.isBlank(phoneNo)) {
            errorMessage.append(String.format("[%s]", "收货人联系电话不能为空!"));
        }
        if (StringUtils.isBlank(receiverName)) {
            errorMessage.append(String.format("[%s]", "收货人姓名不能为空!"));
        }
        if (StringUtils.isBlank(areaId)) {
            errorMessage.append(String.format("[%s]","区域ID不能为空!"));
        }
        if (StringUtils.isBlank(address)) {
            errorMessage.append(String.format("[%s]","详细收货地址不能为空!"));
        }
        if (StringUtils.isBlank(smsCode)) {
            errorMessage.append(String.format("[%s]","短信验证码不能为空!"));
        }
        if (StringUtils.isNotBlank(errorMessage.toString())) {
            throw new BusiException(errorMessage.toString());
        }
        // 验证码校验.
        String smsCodeCache = (String)request.getSession().getAttribute("smsCode");
        if (!smsCode.equalsIgnoreCase(smsCodeCache)) {
            redirectAttributes.addFlashAttribute("errorMessage", "短信验证码校验失败!");
            return REDIRECT_PAGE;
        }

        // 判断用户是否注册过.
        String retCode = miMemberService.hadExistAutoRegister(phoneNo, receiverName);
        if (Dict.Sys_User.RegisterStatusCode.AUTO_REGISTER_FAIL.getCode().equalsIgnoreCase(retCode)) {
            throw new BusiException("系统异常:用户自动注册失败!业务操作无法进行!");
        } else if (Dict.Sys_User.RegisterStatusCode.AUTO_REGISTER_SUCCESS.getCode().equalsIgnoreCase(retCode)) {
            if (logger.isDebugEnabled()) {
                logger.info(Dict.Sys_User.RegisterStatusCode.AUTO_REGISTER_SUCCESS.getName());
            }
        } else if (Dict.Sys_User.RegisterStatusCode.HAD_EXIST.getCode().equalsIgnoreCase(retCode)) {
            if (logger.isDebugEnabled()) {
                logger.info(Dict.Sys_User.RegisterStatusCode.HAD_EXIST.getName());
            }
        }

        // 重复订单提交校验.(通过令牌校验.)
        String orderToken = request.getParameter("orderToken");
        HttpSession session = request.getSession();
        String orderTokenCache = (String) session.getAttribute("orderToken");
        if (StringUtils.isNotBlank(orderToken) && orderToken.equalsIgnoreCase(orderTokenCache)) {
            session.removeAttribute("orderToken");
        } else {
            redirectAttributes.addFlashAttribute("errorMessage", "重复订单!");
            return REDIRECT_PAGE;
        }

        String requestBody = null;
        Map<String, String> params = new HashMap<>();
        params.put("areaId", areaId);
        params.put("phoneNo", phoneNo);
        params.put("receiverName", receiverName);
        params.put("address", address);
        /*
            购物车页面->订单确认页面->{提交并支付订单}
         */
        if ("cart".equalsIgnoreCase(from)) {
            String cartId = request.getParameter("cartId");
            params.put("from", "cart");
            String cartItemIds = request.getParameter("cartItemIds");
            params.put("cartItemIds", cartItemIds);
            try{
                requestBody = busiOrderService.genOrderByCartId(cartId, params);
            }catch (Exception e){
//                request.setAttribute("errorMessage",e.getMessage());
                logger.error(e.getMessage());
                redirectAttributes.addFlashAttribute("errorMessage", "订单异常请重新下单!");
                return REDIRECT_PAGE;
            }
        }

        /*
            用户从产品详情页->订单确认页面->{提交并支付订单}
         */
        if ("productDetail".equalsIgnoreCase(from)) {
            String sum = request.getParameter("sum");
            String productId = request.getParameter("productId");
            params.put("sum", sum);
            params.put("from", "productDetail");
            // 生成环迅支付的报文.
            try{
                requestBody = busiOrderService.genOrderByProductId(productId, params);
            }catch (Exception e){
//                request.setAttribute("errorMessage", e.getMessage());
                logger.error(e.getMessage());
                redirectAttributes.addFlashAttribute("errorMessage", "订单异常请重新下单!");
                return REDIRECT_PAGE;
            }
        }
        // 返回环迅支付的报文.
        request.setAttribute("requestBody", requestBody);
        return "order/payment";
    }

    /**
     * 订单详情页->订单确认页面.
     * 购物车页面->订单确认页面.
     * @return
     */
    @RequestMapping("/confirmPage")
    public String confirmPage(HttpServletRequest request) {
        String mode = request.getParameter("mode");
        String from = request.getParameter("from");
        String orderToken = request.getParameter("orderToken");
        String cartItemIds = request.getParameter("cartItemIds");

        if ("productDetail".equalsIgnoreCase(from)) {
            String productId = request.getParameter("productId");
            BusiProduct productQuery = new BusiProduct();
            productQuery.setId(productId);
            BusiProduct product = busiProductService.selectById(productQuery);
            logger.info("mode:[{}]-from[{}]-product:[{}]", mode, from, JSONObject.toJSONString(product));
            request.setAttribute("product",product);
            request.setAttribute("devMode", "dev".equalsIgnoreCase(mode)?JSONObject.toJSONString(product):"");
        }

        if ("cart".equalsIgnoreCase(from)) {
            String cartId = request.getParameter("cartId");
            BusiCart busiCartQuery = new BusiCart();
            busiCartQuery.setId(cartId);
            BusiCart busiCart = busiCartService.selectById(busiCartQuery);
            CartVO cartvo = new CartVO();
            if (null != busiCart) {
                EntityWrapper<BusiCartDetailItem> entityWrapper = new EntityWrapper<>();
                if (!StringUtils.isNotBlank(cartItemIds)) {
                    logger.error("选中的购物车明细项为空!");
                    throw new BusiException("选中的购物车明细项为空!");
                }
                String[] ids = cartItemIds.split(",");
                List<BusiCartDetailItem> cartDetailItems = new ArrayList<>();
                for (String id : ids) {
                    BusiCartDetailItem cartDetailItemQuery = new BusiCartDetailItem();
                    cartDetailItemQuery.setId(id);
                    cartDetailItemQuery.setCartId(busiCart.getId());
                    entityWrapper.setEntity(cartDetailItemQuery);
                    List<BusiCartDetailItem> list = busiCartDetailItemService.selectList(entityWrapper);
                    if (null != list && !list.isEmpty()) {
                        cartDetailItems.add(list.get(0));
                    }
                }
                orderToken = MD5Util.getMD5String(ValidateUtil.genSmsValidateCode());
                request.getSession().setAttribute("orderToken", orderToken);
                request.setAttribute("cartItemIds", cartItemIds);
                cartvo.setCartItems(cartDetailItems);
                BeanUtils.copy(busiCart, cartvo);
            } else {
                request.setAttribute("errorMessage", "查无此购物车!");
            }
            request.setAttribute("cartvo", cartvo);
            logger.info("mode:[{}]-from:[{}]-product:[{}]", mode, JSONObject.toJSONString(cartvo));
            request.setAttribute("devMode", "dev".equalsIgnoreCase(mode)?JSONObject.toJSONString(cartvo):"");
        }
        request.setAttribute("orderToken", orderToken);
        request.setAttribute("from", from);
        return "order/order_confirm";
    }


    /**
     * 添加
     * @param 
     * @return
     */
    @RequestMapping("/toPay")
    public Object add(HttpServletRequest request) {
        String orderId = request.getParameter("orderId");
        BusiOrder busiOrderQuery = new BusiOrder();
        busiOrderQuery.setId(orderId);
        BusiOrder busiOrder = busiOrderService.selectById(busiOrderQuery);
        String orderNo = busiOrder.getOrderNo();
        EntityWrapper<BusiOrderItem> entityWrapper = new EntityWrapper<BusiOrderItem>();
        BusiOrderItem orderItemQuery = new BusiOrderItem();
        orderItemQuery.setOrderId(orderId);
        List<BusiOrderItem> busiOrderItems = busiOrderItemService.selectList(entityWrapper);
        BusiOrderItem orderItem = null;
        if (null != busiOrderItems && !busiOrderItems.isEmpty()) {
            orderItem = busiOrderItems.get(0);
        }
        String productName = orderItem.getProdName()+"等";
        String requestBody = ISPaymentRequest.genPayRequestMessage(orderNo, productName,"WS"+busiOrder.getRecPhone(), busiOrder.getStandy1());
        // 返回环迅支付的报文.
        request.setAttribute("requestBody", requestBody);
        return "order/payment";
    }

    /**
     * 获取确认订单页面
     * @param
     * @return
     */
    @RequestMapping("/disQuery")
    public void disQuery(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            response.setContentType("application/json;charset=utf-8");
            response.setCharacterEncoding("utf-8");
            String phoneNo = request.getParameter("phoneNo");
            String smsCode = request.getParameter("smsCode");
            String totalAmount = request.getParameter("totalAmount");
            JsonResult jsonResult = new JsonResult();
            logger.debug("参数校验start...");
            StringBuilder errorMessage = new StringBuilder();
            if (StringUtils.isBlank(phoneNo)) {
                errorMessage.append("手机号不能为空!");
            }
            if (StringUtils.isBlank(smsCode)) {
                errorMessage.append("短信验证码不能为空!");
            }
            if (StringUtils.isBlank(totalAmount)) {
                errorMessage.append("总价不能为空!");
            }
            logger.debug("参数校验end...");

            if (StringUtils.isNotBlank(errorMessage.toString())) {
                PrintWriter writer = response.getWriter();
                jsonResult.setStatus(JsonResult.PARAMETER_EMPTY.getCode());
                jsonResult.setMsg(String.format("请求失败![%s]", errorMessage.toString()));
                writer.write(JSONObject.toJSONString(jsonResult));
                return;
            }
            logger.debug("短信校验start...");
            String smsCodeCache = (String) request.getSession().getAttribute("smsCode");
            if (!smsCode.equalsIgnoreCase(smsCodeCache)) {
                PrintWriter writer = response.getWriter();
                jsonResult.setStatus(JsonResult.FAIL.getCode());
                jsonResult.setMsg("短信验证码校验失败!");
                writer.write(JSONObject.toJSONString(jsonResult));
                return;
            }
            logger.debug("短信校验end...");
            // 查询用户的折扣.
            Map map = discountStrategy.doDiscount("WS" + phoneNo, totalAmount);
            String discountPrice = (String)map.get("discountPrice");
            jsonResult.setMsg(JsonResult.SUCCESS.getDesc());
            jsonResult.setData(discountPrice);
            jsonResult.setStatus(JsonResult.SUCCESS.getCode());
            PrintWriter writer = response.getWriter();
            writer.write(JSONObject.toJSONString(jsonResult));
        }catch (Throwable e){
            e.printStackTrace();
            logger.error(e.getMessage());
        }
    }


    /**
     * 取消订单.
     * @param id
     * @return
     */
    @RequestMapping("/delete")
    @ResponseBody
    public Object delete(String id) {
        if (logger.isDebugEnabled()) {
            logger.info("取消订单id:[{}]", id);
        }
        BusiOrder busiOrder = new BusiOrder();
        busiOrder.setId(id);
        busiOrder.setUpdateaTime(DateUtil.convertDateToStr(new Date(), DateUtil.DEFAULT_DATE_FORMAT));
        busiOrder.setDataStatus(Dict.YesOrNo.No.getCode());
        boolean b = busiOrderService.updateById(busiOrder);
        if (logger.isDebugEnabled()) {
            logger.info("取消结果[{}]", b);
        }
        if (b) {
            return renderSuccess("删除成功！");
        } else {
            return renderError("删除失败！");
        }
    }

    /**
     * 判断订单Token是否存在
     * 存在，让用户填写信息并提交.
     * 不存在，让用户回到首页继续下单.
     */
    @RequestMapping("/orderToken")
    @ResponseBody
    public Object judgeOrderTokenIsExsit(HttpServletRequest request){
        HttpSession session = request.getSession();
        String orderTokenCache = (String)session.getAttribute("orderToken");
        if (StringUtils.isBlank(orderTokenCache)) {
            return write2Json(null, Boolean.FALSE, "orderToken is null.please go to home page.", null);
        }
        return write2Json(null, Boolean.TRUE, "orderToken is not null.you can commit this order.", null);
    }

    /**
     * 编辑
     * @param model
     * @param id
     * @return
     */
    @RequestMapping("/editPage")
    public String editPage(Model model, Long id) {
        BusiOrder busiOrder = busiOrderService.selectById(id);
        model.addAttribute("busiOrder", busiOrder);
        return "admin/busiOrder/busiOrderEdit";
    }

    /**
     * 编辑
     * @param 
     * @return
     */
    @RequestMapping("/askphone")
    public String askphone(HttpServletRequest request) {
        return "order/askphone";
    }
    
}
